using UnityEditor;
using UnityEngine;

namespace FShaderInspector
{
    /// <summary> 材质球编辑器扩展 </summary>
    public static class MaterialEditorExtension
    {
        /// <summary> 获取 MaterialProperty 的 Rect </summary>
        /// <param name="prop">属性</param> <returns>Rect</returns>
        static Rect GetRect(MaterialProperty prop)
        {
            return EditorGUILayout.GetControlRect(true, MaterialEditor.GetDefaultPropertyHeight(prop), EditorStyles.layerMaskField);
        }

        /// <summary> int 着色器属性的整数滑块。 </summary>
        /// <param name="editor">this</param> <param name="prop">属性</param> <param name="min">最小值</param> <param name="max">最大值</param> <param name="label">标签</param>
        public static void IntSliderShaderProperty(this MaterialEditor editor, MaterialProperty prop, int min, int max, string label)
        {
            MaterialEditor.BeginProperty(prop);

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = prop.hasMixedValue;
            int newValue = EditorGUI.IntSlider(GetRect(prop), label, (int)prop.floatValue, min, max);
            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck())
            {
                editor.RegisterPropertyChangeUndo(label);
                prop.floatValue = newValue;
            }

            MaterialEditor.EndProperty();
        }

        /// <summary> vector2 着色器属性 </summary>
        /// <param name="editor">this</param> <param name="prop">属性</param> <param name="label">标签</param>
        public static void Vector2ShaderProperty(this MaterialEditor editor, MaterialProperty prop, string label)
        {
            MaterialEditor.BeginProperty(prop);

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = prop.hasMixedValue;
            // var newValue = EditorGUI.Vector2Field(GetRect(prop), label, prop.vectorValue);
            var newValue = EditorGUILayout.Vector2Field(label, prop.vectorValue);

            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck())
            {
                editor.RegisterPropertyChangeUndo(label);
                prop.vectorValue = newValue;
            }

            MaterialEditor.EndProperty();
        }

        /// <summary> vector3 着色器属性 </summary>
        /// <param name="editor">this</param> <param name="prop">属性</param> <param name="label">标签</param>
        public static void Vector3ShaderProperty(this MaterialEditor editor, MaterialProperty prop, string label)
        {
            MaterialEditor.BeginProperty(prop);

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = prop.hasMixedValue;
            var newValue = EditorGUILayout.Vector3Field(label, prop.vectorValue);
            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck())
            {
                editor.RegisterPropertyChangeUndo(label);
                prop.vectorValue = newValue;
            }

            MaterialEditor.EndProperty();
        }

        /// <summary> vector4 着色器属性 </summary>
        /// <param name="editor">this</param> <param name="prop">属性</param> <param name="label">标签</param>
        public static void Vector4ShaderProperty(this MaterialEditor editor, MaterialProperty prop, string label)
        {
            MaterialEditor.BeginProperty(prop);

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = prop.hasMixedValue;
            var newValue = EditorGUILayout.Vector4Field(label, prop.vectorValue);
            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck())
            {
                editor.RegisterPropertyChangeUndo(label);
                prop.vectorValue = newValue;
            }

            MaterialEditor.EndProperty();
        }

        /// <summary> int 弹窗着色器属性 </summary>
        /// <param name="editor">this</param> <param name="prop">属性</param> <param name="label">标签</param> <param name="displayedOptions">显示选项</param> <returns>index</returns>
        public static int PopupShaderProperty(this MaterialEditor editor, MaterialProperty prop, string label, string[] displayedOptions)
        {
            MaterialEditor.BeginProperty(prop);

            int value = (int)prop.floatValue;

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = prop.hasMixedValue;
            int newValue = EditorGUILayout.Popup(label, value, displayedOptions);
            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck() && (newValue != value || prop.hasMixedValue))
            {
                editor.RegisterPropertyChangeUndo(label);
                prop.floatValue = value = newValue;
            }

            MaterialEditor.EndProperty();

            return value;
        }

        /// <summary> int 开关着色器属性 </summary>
        /// <param name="editor">this</param> <param name="prop">属性</param> <param name="label">标签</param> <returns>开关</returns>
        public static bool ToggleShaderProperty(this MaterialEditor editor, MaterialProperty prop, string label)
        {
            MaterialEditor.BeginProperty(prop);

            bool val = (int)prop.floatValue == 1;

            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = prop.hasMixedValue;
            bool newValue = EditorGUILayout.Toggle(label, val);
            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck() && (newValue != val || prop.hasMixedValue))
            {
                editor.RegisterPropertyChangeUndo(label);
                prop.floatValue = newValue ? 1 : 0;
            }

            MaterialEditor.EndProperty();
            return val;
        }
    }
}